package com.zbkj.crmeb.store.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.constants.WeChatConstants;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.RedisUtil;
import com.github.pagehelper.PageInfo;
import com.utils.CrmebUtil;
import com.utils.DateUtil;
import com.utils.vo.dateLimitUtilVo;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.statistics.service.impl.HomeServiceImpl;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.response.DataLiveSingleResponse;
import com.zbkj.crmeb.store.response.RefundProductBoardResponse;
import com.zbkj.crmeb.store.service.*;
import com.zbkj.crmeb.system.service.SystemConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class TransactionAnalysisServiceImpl implements TransactionAnalysisService {

    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Autowired
    private HomeServiceImpl homeServiceImpl;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private StoreSaleAnalysisService storeSaleAnalysisService;
    @Autowired
    private StoreOrderService storeOrderService;
    @Autowired
    private DataLiveServiceImpl dataLiveServiceImpl;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Autowired
    private StoreOrderStatusService storeOrderStatusService;
    @Autowired
    private StoreProductService storeProductService;

    @Value("${server.wechatProgramToken}")
    private Boolean programTokenFlag;

    /**
     * 功能描述: 获取时间段内交易转化数据
     * @Param: [dateLimit, merId]
     * @Return: java.util.Map<java.lang.String,java.lang.Object>
     * @Author: wangzh
     * @Date: 2023/1/3 14:43
     */
    @Override
    public Map<String, Object> transactionConversion(dateLimitUtilVo dateLimit, Integer merId) {
        Map<String, Object> response = new HashMap<>();
        LocalDate startDay = LocalDate.parse(dateLimit.getStartTime());
        LocalDate endDay = LocalDate.parse(dateLimit.getEndTime());
        //时间段内总访客量
        int sumVisitor = 0;
        //访客数
        if (!programTokenFlag){
            response.put("visitor", sumVisitor);
        } else {
            ChannelMerchant channelMerchant = channelMerchantService.getById(merId);
            log.info("----------------- 获取小程序访问量,商户id:{} -----------------", channelMerchant.getId());
            try {
                //反射获取私有方法
                Method getAccessToken = BeanUtils.findDeclaredMethod(homeServiceImpl.getClass(), "getAccessToken", String.class, String.class);
                if (getAccessToken != null) {
                    getAccessToken.setAccessible(true);
                }
                //反射获取日趋势私有方法
                Method getDailyVisitTrend = BeanUtils.findDeclaredMethod(homeServiceImpl.getClass(), "getDailyVisitTrend", String.class, String.class);
                if (getDailyVisitTrend != null) {
                    getDailyVisitTrend.setAccessible(true);
                }
                String accessToken = (String) redisUtil.get(WeChatConstants.REDIS_PROGRAM_TOKEN_KEY + "_" + channelMerchant.getId());
                //redis中token到期，自动请求新token
                if (StringUtils.isBlank(accessToken)) {
                    String appId = systemConfigService.getValueByKey("routine_appid_" + channelMerchant.getId());
                    String secret = systemConfigService.getValueByKey("routine_appsecret_" + channelMerchant.getId());
                    if (StringUtils.isNotBlank(appId) && StringUtils.isNotBlank(secret)) {
                        JSONObject jsonObject = (JSONObject) getAccessToken.invoke(homeServiceImpl, appId, secret);
                        if (jsonObject != null) {
                            accessToken = jsonObject.get("access_token").toString();
                            long expires = Long.parseLong(jsonObject.getString("expires_in"));
                            redisUtil.set(WeChatConstants.REDIS_PROGRAM_TOKEN_KEY + "_" + channelMerchant.getId(), accessToken, expires - 100, TimeUnit.SECONDS);
                        }
                    } else {
                        log.info("-----------获取小程序访问量失败,商户appid或appsecret不存在,商户id:{} -----------", channelMerchant.getId());
                    }
                }
                while (startDay.isBefore(endDay)){
                    String date = startDay.format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_NUM));
                    //商户创建时间大于查询时间,访问量为0
                    if (channelMerchant.getCreateTime().after(Date.from(startDay.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()))){
                        startDay = startDay.plusDays(1);
                        continue;
                    }
                    //从缓存中读取
                    Object dateCount = redisUtil.get(StrUtil.format(Constants.APPLET_VISIT_PV, channelMerchant.getId(), date));
                    if (Objects.isNull(dateCount)){
                        Integer dailyVisitTrend = (Integer) getDailyVisitTrend.invoke(homeServiceImpl, accessToken, date);
                        if (Objects.nonNull(dailyVisitTrend)){
                            dateCount = dailyVisitTrend;
                            redisUtil.set(StrUtil.format(Constants.APPLET_VISIT_PV, channelMerchant.getId(), date), dailyVisitTrend, 30L, TimeUnit.DAYS);
                        } else {
                            dateCount = 0;
                        }
                    }
                    sumVisitor += (Integer) dateCount;
                    startDay = startDay.plusDays(1);
                }
                response.put("visitor", sumVisitor);
            } catch (Exception e){
                e.printStackTrace();
                log.error("--------------获取小程序访问次数异常,商户id:{},msg:{}---------------", channelMerchant.getId(), e.getMessage());
            }
        }
        //商品浏览人数
        QueryWrapper<StoreProductActive> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(visitor_number) as visitor_number").lambda()
                .eq(StoreProductActive::getMerId, merId)
                .between(StoreProductActive::getUpdateTime, dateLimit.getStartTime(), endDay)
                .last("limit 1");
        StoreProductActive one = storeSaleAnalysisService.getOne(queryWrapper);
        if (Objects.isNull(one)){
            one = new StoreProductActive();
            one.setVisitorNumber(0);
        }
        //商品浏览人数
        Integer visitorNumber = one.getVisitorNumber();
        response.put("productVisitorNumber", visitorNumber);
        //客单价
        QueryWrapper<StoreOrder> storeOrderQueryWrapper = new QueryWrapper<>();
        storeOrderQueryWrapper.select("count(*) as total_num", "sum(pay_price) as pay_price")
                .lambda().eq(StoreOrder::getMerId, merId)
                .between(StoreOrder::getCreateTime, dateLimit.getStartTime(), endDay)
                .ne(StoreOrder::getStatus, 0)
                .ne(StoreOrder::getStatus, 5)
                .last("limit 1");
        StoreOrder storeOrder = storeOrderService.getOne(storeOrderQueryWrapper);
        if (Objects.isNull(storeOrder.getPayPrice())){
            storeOrder.setPayPrice(BigDecimal.ZERO);
        }
        //支付次数
        Integer payProductNumber = storeOrder.getTotalNum();
        //支付金额
        BigDecimal payPrice = storeOrder.getPayPrice();
        response.put("payTime", payProductNumber);
        response.put("payPrice", payPrice);
        BigDecimal customerUnitPrice = storeOrder.getPayPrice();
        if (storeOrder.getTotalNum() > 0){
            customerUnitPrice = storeOrder.getPayPrice().divide(new BigDecimal(storeOrder.getTotalNum()), 2, RoundingMode.HALF_UP);
        }
        response.put("customerUnitPrice", customerUnitPrice);
        //访问-商品转化率
        BigDecimal visitToProduct = new BigDecimal(visitorNumber).multiply(new BigDecimal(100));
        if (sumVisitor > 0){
            visitToProduct = new BigDecimal(visitorNumber).divide(new BigDecimal(sumVisitor), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
        }
        response.put("visitToProduct", visitToProduct + "%");
        //商品-支付转化率
        BigDecimal productToPay = new BigDecimal(payProductNumber).multiply(new BigDecimal(100));
        if (visitorNumber > 0){
            productToPay = new BigDecimal(payProductNumber).divide(new BigDecimal(visitorNumber), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
        }
        response.put("productToPay", productToPay + "%");
        return response;
    }

    /**
     * 功能描述: 获取时间段内退款数据
     * @Param: [dateLimit, merId]
     * @Return: java.util.Map<java.lang.Object,java.lang.Object>
     * @Author: wangzh
     * @Date: 2023/1/3 14:43
     */
    @Override
    public Map<Object, Object> refundBoard(dateLimitUtilVo dateLimit, Integer merId) {
        Map<Object, Object> response = new HashMap<>();
        //加1算上当前月
        int interval = (int) (LocalDate.parse(dateLimit.getStartTime()).until(LocalDate.parse(dateLimit.getEndTime()), ChronoUnit.MONTHS) + 1);
        if (interval > 3){
            throw new CrmebException("月份超出限制，最大选取三个月");
        }
        LocalDate localDate = LocalDate.parse(dateLimit.getStartTime());
        LocalDate localDate1 = LocalDate.parse(dateLimit.getEndTime());
        //相差天数 包含最后一天
        int len = (int) localDate.until(localDate1, ChronoUnit.DAYS) + 1;
        int intervalDay = 0;
        if (len % 15 < 7) {
            intervalDay = len / 15;
        } else {
            intervalDay = len / 15 + 1;
        }
        //时间列表
        List<String> listDateMonth = DateUtil.getListDateMonth(dateLimit, 15);
        //计算上期的开始与结束时间
        String previousPeriodStartTime = LocalDate.parse(listDateMonth.get(0)).minusMonths(interval).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_START));
        String previousPeriodEndTime = LocalDate.parse(listDateMonth.get(listDateMonth.size() - 1)).minusMonths(interval).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END));
        dateLimitUtilVo previousDateLimit = new dateLimitUtilVo(previousPeriodStartTime, previousPeriodEndTime);

        //退款金额方法
        Method getWholeRefundPrice = BeanUtils.findDeclaredMethod(dataLiveServiceImpl.getClass(), "getWholeRefundPrice", List.class, List.class, dateLimitUtilVo.class, Integer.class);
        if (Objects.nonNull(getWholeRefundPrice)){
            getWholeRefundPrice.setAccessible(true);
        }
        DataLiveSingleResponse refundPrice = new DataLiveSingleResponse();
        try {
            refundPrice = (DataLiveSingleResponse) getWholeRefundPrice.invoke(dataLiveServiceImpl, listDateMonth, Arrays.asList(merId), previousDateLimit, intervalDay);
        } catch (Exception e) {
            e.printStackTrace();
        }
        response.put("refundPrice", refundPrice);
        //退款笔数
        response.put("refundTime", getRefundTime(listDateMonth, merId, previousDateLimit, intervalDay));
        //退款率
        response.put("refundRate", getRefundRate(listDateMonth, merId, previousDateLimit, intervalDay));

        return response;
    }

    @Override
    public PageInfo<RefundProductBoardResponse> refundProduct(PageParamRequest request, Integer merId) {
        LocalDateTime now = LocalDateTime.now();
        //一个月前的时间
        String localDateTime = now.minusMonths(1).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_START));
        //每件商品成功退款订单数
        Map<Integer, Integer> refundNumberMap = new HashMap<>();

        QueryWrapper<StoreOrderInfo> infoQueryWrapper = new QueryWrapper<>();
        infoQueryWrapper.select("count(*) as id, product_id")
                .lambda().ne(StoreOrderInfo::getRefundStatus, 0)
                .ne(StoreOrderInfo::getRefundStatus, 1)
                .ge(StoreOrderInfo::getCreateTime, localDateTime)
                .groupBy(StoreOrderInfo::getProductId);
        //每件商品成功退款订单数
        List<StoreOrderInfo> infoList = storeOrderInfoService.list(infoQueryWrapper);
        if (CollectionUtils.isNotEmpty(infoList)){
            refundNumberMap = infoList.stream().collect(Collectors.toMap(StoreOrderInfo::getProductId, StoreOrderInfo::getId));
        }
        //每件商品成功支付订单数
        Map<Integer, Integer> payNumberMap = new HashMap<>();
        QueryWrapper<StoreOrderInfo> storeOrderInfoQueryWrapper = new QueryWrapper<>();
        storeOrderInfoQueryWrapper.select("count(*) as id, product_id")
                        .lambda().ge(StoreOrderInfo::getCreateTime, localDateTime)
                        .ne(StoreOrderInfo::getStatus, 0)
                        .ne(StoreOrderInfo::getStatus, 5)
                        .groupBy(StoreOrderInfo::getProductId);
        List<StoreOrderInfo> storeOrderInfos = storeOrderInfoService.list(storeOrderInfoQueryWrapper);
        if (CollectionUtils.isNotEmpty(storeOrderInfos)){
            payNumberMap = storeOrderInfos.stream().collect(Collectors.toMap(StoreOrderInfo::getProductId, StoreOrderInfo::getId));
        }
        //商品对应退款率
        Map<Integer, BigDecimal> rateMap = new HashMap<>();
        for (Map.Entry entry : refundNumberMap.entrySet()){
            //商品id
            Integer productId = (Integer) entry.getKey();
            //支付数量
            Integer number = payNumberMap.get(productId);
            //支付数量为空，退款率为100%
            BigDecimal rate = new BigDecimal("100.00");
            //支付数量不为空，计算退款率
            if (Objects.nonNull(number)){
                rate = new BigDecimal((Integer) entry.getValue()).divide(new BigDecimal(number), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
            }
            rateMap.put(productId, rate);
        }
        //退款信息
        Map<Integer, StoreProductActive> productRefundInfoMap = new HashMap<>();
        //商品详情
        Map<Integer, StoreProduct> productMap = new HashMap<>();
        //查询商品在最近30天的成功退款金额，成功退款笔数，支付金额
        if (CollectionUtils.isNotEmpty(rateMap.keySet())){
            QueryWrapper<StoreProductActive> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("product_id", "sum(refund_amount) as refund_amount", "sum(refund_number) as refund_number", "sum(payment_amount) as payment_amount")
                    .lambda().ge(StoreProductActive::getUpdateTime, localDateTime)
                    .eq(StoreProductActive::getMerId, merId)
                    .in(StoreProductActive::getProductId, new ArrayList<>(rateMap.keySet()))
                    .gt(StoreProductActive::getPaymentAmount, 0)
                    .groupBy(StoreProductActive::getProductId);
            //近30天内商品
            List<StoreProductActive> list = storeSaleAnalysisService.list(queryWrapper);
            if (CollectionUtils.isNotEmpty(list)){
                //退款信息
                productRefundInfoMap = list.stream().collect(Collectors.toMap(StoreProductActive::getProductId, e -> e));
            }
            List<StoreProduct> listInIds = storeProductService.getListInIds(new ArrayList<>(rateMap.keySet()));
            if (CollectionUtils.isNotEmpty(listInIds)){
                //商品详情
                productMap = listInIds.stream().collect(Collectors.toMap(StoreProduct::getId, e -> e));
            }
        }
        rateMap = sortMap(rateMap);
        List<RefundProductBoardResponse> responses = new ArrayList<>();
        int sort = 1;
        //循环赋值
        for (Integer productId : rateMap.keySet()){
            RefundProductBoardResponse one = new RefundProductBoardResponse();
            StoreProductActive storeProductActive = productRefundInfoMap.get(productId);
            if (Objects.isNull(storeProductActive)){
                storeProductActive = new StoreProductActive();
                storeProductActive.setRefundAmount(BigDecimal.ZERO).setRefundNumber(0).setPaymentAmount(BigDecimal.ZERO);
            }
            one.setSort(sort).setStoreProduct(productMap.get(productId)).setSuccessPrice(storeProductActive.getRefundAmount())
                    .setSuccessNum(storeProductActive.getRefundNumber()).setPayPrice(storeProductActive.getPaymentAmount())
                    .setRate(rateMap.get(productId) + "%");
            responses.add(one);
            sort ++;
        }
        //构造分页信息
        PageInfo<RefundProductBoardResponse> page = new PageInfo<>();
        page.setTotal(responses.size());
        page.setPages(responses.size() / request.getLimit() + 1);
        page.setPageNum(request.getPage());
        page.setPageSize(request.getLimit());
        page.setList(responses.stream().skip((long) (request.getPage() - 1) * request.getLimit()).limit(request.getLimit()).collect(Collectors.toList()));
        return page;
    }

    /**
     * 功能描述: 获取退款笔数
     * @Param: [dateList, merId, dateLimit, intevalDay]
     * @Return: com.zbkj.crmeb.store.response.DataLiveSingleResponse
     * @Author: wangzh
     * @Date: 2023/1/3 15:15
     */
    private DataLiveSingleResponse getRefundTime(List<String> dateList, Integer merId, dateLimitUtilVo dateLimit, Integer intervalDay){
        Integer present = getSumRefundTime(new dateLimitUtilVo(LocalDate.parse(dateList.get(0)).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_START)), LocalDate.parse(dateList.get(dateList.size() - 1)).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END))), merId);
        Integer previous = getSumRefundTime(dateLimit, merId);
        BigDecimal rate = CrmebUtil.getRateDecimal(present, previous);
        Map<Object, Object> refundTimeMap = new LinkedHashMap<>();
        refundTimeMap.put(LocalDate.parse(dateList.get(0)).minusDays(intervalDay).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_DATE)) + "~" + dateList.get(0), getSumRefundTime(new dateLimitUtilVo(LocalDate.parse(dateList.get(0)).minusDays(intervalDay).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_START)), LocalDate.parse(dateList.get(0)).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END))), merId));
        for (int i = 0; i < dateList.size() - 1; i++) {
            String start = LocalDate.parse(dateList.get(i)).plusDays(1).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_START));
            String end = LocalDate.parse(dateList.get(i + 1)).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END));
            refundTimeMap.put(LocalDate.parse(dateList.get(i)).plusDays(1) + "~" + dateList.get(i + 1), getSumRefundTime(new dateLimitUtilVo(start, end), merId));
        }
        refundTimeMap = CrmebUtil.convertKey(refundTimeMap);
        DataLiveSingleResponse response = new DataLiveSingleResponse();
        response.setTodayCount(present)
                .setYesterdayCount(previous)
                .setMonthRate(rate + "%")
                .setLineChart(refundTimeMap);
        return response;
    }

    /**
     * 功能描述: 获取退款率
     * @Param: [merId]
     * @Return: com.zbkj.crmeb.store.response.DataLiveSingleResponse
     * @Author: wangzh
     * @Date: 2023/1/3 16:05
     */
    private DataLiveSingleResponse getRefundRate(List<String> dateList, Integer merId, dateLimitUtilVo dateLimit, Integer intervalDay){
        BigDecimal present = getSumRefundRate(new dateLimitUtilVo(LocalDate.parse(dateList.get(0)).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_START)), LocalDate.parse(dateList.get(dateList.size() - 1)).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END))), merId);
        BigDecimal previous = getSumRefundRate(dateLimit, merId);
        BigDecimal rate = CrmebUtil.getRateDecimal(present, previous);
        Map<Object, Object> refundRateMap = new LinkedHashMap<>();
        refundRateMap.put(LocalDate.parse(dateList.get(0)).minusDays(intervalDay).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_DATE)) + "~" + dateList.get(0), getSumRefundRate(new dateLimitUtilVo(LocalDate.parse(dateList.get(0)).minusDays(intervalDay).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_START)), LocalDate.parse(dateList.get(0)).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END))), merId));
        for (int i = 0; i < dateList.size() - 1; i++) {
            String start = LocalDate.parse(dateList.get(i)).plusDays(1).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_START));
            String end = LocalDate.parse(dateList.get(i + 1)).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END));
            refundRateMap.put(LocalDate.parse(dateList.get(i)).plusDays(1) + "~" + dateList.get(i + 1), getSumRefundRate(new dateLimitUtilVo(start, end), merId));
        }
        refundRateMap = CrmebUtil.convertKey(refundRateMap);
        DataLiveSingleResponse response = new DataLiveSingleResponse();
        response.setTodayCount(present)
                .setYesterdayCount(previous)
                .setMonthRate(rate + "%")
                .setLineChart(refundRateMap);
        return response;
    }

    /**
     * 功能描述: 获取指定时间内的退款率
     * @Param: [dateLimit, merId]
     * @Return: java.math.BigDecimal
     * @Author: wangzh
     * @Date: 2023/1/3 18:04
     */
    private BigDecimal getSumRefundRate(dateLimitUtilVo dateLimit, Integer merId){
        List<StoreOrder> list = storeOrderService.list(Wrappers.<StoreOrder>lambdaQuery()
                .eq(StoreOrder::getMerId, merId)
                .between(StoreOrder::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime()));
        if (CollectionUtils.isEmpty(list)){
            return BigDecimal.ZERO;
        }
        List<Integer> orderIds = list.stream().map(StoreOrder::getId).collect(Collectors.toList());
        //退款订单数
        int refundOrderNum = storeOrderStatusService.selectRefundNum(orderIds, dateLimit);
        //支付成功订单数
        int payOrderNum = storeOrderInfoService.count(Wrappers.<StoreOrderInfo>lambdaQuery()
                .in(StoreOrderInfo::getOrderId, orderIds)
                .between(StoreOrderInfo::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime()));
        if (payOrderNum > 0){
            return new BigDecimal(refundOrderNum).divide(new BigDecimal(payOrderNum), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
        }
        return new BigDecimal(refundOrderNum).multiply(new BigDecimal(100));
    }

    /**
     * 功能描述: 获取指定时间内的退款笔数
     * @Param: [dateLimit, merId]
     * @Return: java.lang.Integer
     * @Author: wangzh
     * @Date: 2023/1/3 18:04
     */
    private Integer getSumRefundTime(dateLimitUtilVo dateLimit, Integer merId){
        QueryWrapper<StoreProductActive> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(refund_number) as refund_number")
                .lambda().eq(StoreProductActive::getMerId, merId)
                .between(StoreProductActive::getUpdateTime, dateLimit.getStartTime(), dateLimit.getEndTime())
                .last("limit 1");
        StoreProductActive one = storeSaleAnalysisService.getOne(queryWrapper);
        if (Objects.isNull(one)){
            return 0;
        }
        return one.getRefundNumber();
    }

    /**
     * 功能描述: 按照value排序map
     * @Param: [map]
     * @Return: java.util.Map<java.lang.Integer,java.math.BigDecimal>
     * @Author: wangzh
     * @Date: 2023/1/4 13:55
     */
    private Map<Integer, BigDecimal> sortMap(Map<Integer, BigDecimal> map){
        //利用Map的entrySet方法，转化为list进行排序
        List<Map.Entry<Integer, BigDecimal>> entryList = new ArrayList<>(map.entrySet());
        //利用Collections的sort方法对list排序
        Collections.sort(entryList, new Comparator<Map.Entry<Integer, BigDecimal>>() {
            @Override
            public int compare(Map.Entry<Integer, BigDecimal> o1, Map.Entry<Integer, BigDecimal> o2) {
                //正序排列，倒序反过来
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        //遍历排序好的list，一定要放进LinkedHashMap，因为只有LinkedHashMap是根据插入顺序进行存储
        LinkedHashMap<Integer, BigDecimal> linkedHashMap = new LinkedHashMap<>();
        for (Map.Entry<Integer,BigDecimal> e : entryList
        ) {
            linkedHashMap.put(e.getKey(),e.getValue());
        }
        return linkedHashMap;
    }
}
